package ntd.util.frame.javacv.ai_fuming;


import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.StaticLog;
import com.google.gson.Gson;
import ntd.util.config.common.enums.protocol.EnumStreamUrlProtocol;
import ntd.util.frame.haikang.remote.RemoteHaiKang;
import ntd.util.frame.haikang.tool.ToolHaiKangVideo;
import ntd.util.frame.javacv.HaikangRtspBean;
import ntd.util.frame.javacv.remote.AiVisionRemote;
import com.c.Constant;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;

import java.io.File;
import java.util.Date;

import static ntd.util.frame.javacv.ComVisionApi.initAiRemote;

/* 功能：录制rtsp等其他视频流保存为视频
  1、根据预警图片获取站点、摄像头编号、分析模型类型
  2、截取1分钟录像
  3、上传mp4文件到对应模型的服务器
  4、通知AI视频分析

 */
public class JavaCvVideoRecord {

    private static int serverIndex = 0;

    public static void recordVideo(String imageName) throws FrameGrabber.Exception, FFmpegFrameRecorder.Exception {
        if (StrUtil.isBlank(imageName)){
            return;
        }
        //输出文件
        String videoName = imageName.replace("-image.jpg","-video.mp4");

        File file = FileUtil.newFile(videoName);

        String[] imageSplit = imageName.split("-");

        String cameraIndexCode = imageSplit[1];
        String imageTime = imageSplit[2];
        String modeType = imageSplit[3];

        Date imageDate = DateUtil.parse(imageTime);

        String beginTime = DateUtil.offsetSecond(imageDate,-15).toString();
        String endTime= DateUtil.offsetSecond(imageDate,10).toString();

        //获取海康录像地址
        HaikangRtspBean bean = getHaikangRtspBean(cameraIndexCode, beginTime, endTime);

        if (StrUtil.isEmpty(bean.getData().getUrl())) {
            StaticLog.info("--===该站点无回放视频："+imageName);
            return;
        }

        //判断是否在视频时间内
        String videoBeginTime = null;
        if (bean.getData().getList() != null && bean.getData().getList().size() > 0){
            videoBeginTime = bean.getData().getList().get(0).getBeginTime();
        }

        videoGet(file, beginTime, bean, videoBeginTime);

        AiVisionRemote aiVisionRemote = initAiRemote().get(serverIndex++ % initAiRemote().size());

//        EnumAIModeType currentMode = EnumUtil.getBy(EnumAIModeType.class, enumAIModeType -> enumAIModeType.getName().equals(modeType));
//        String analyse = aiVisionRemote.analyse(videoName, currentMode, FileUtil.readBytes(file), "-video.mp4");
//        StaticLog.info("视频分析请求结果结果=="+analyse);
    }

    private static void videoGet(File file, String beginTime, HaikangRtspBean bean, String videoBeginTime) throws FrameGrabber.Exception, FFmpegFrameRecorder.Exception {
        //截取图片前后一分钟视频
        JavaCvVideoRecord javaVc = new JavaCvVideoRecord();
        FFmpegFrameGrabber grabber = javaVc.createGrabber(bean.getData().getUrl());

        //流媒体输出地址，分辨率（长，高），1=单声道
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(file,1280,720,1);
        recorder.setFrameRate(grabber.getFrameRate());
        recorder.setFormat("mp4");
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        recorder.setTimestamp(grabber.getTimestamp());

        try{//建议在线程中使用该方法
            long beginNum = DateUtil.between(DateUtil.parse(videoBeginTime), DateUtil.parse(beginTime), DateUnit.SECOND);
//            StaticLog.info("===视频录制开始1");
            grabber.start();
            recorder.start();
//            StaticLog.info("===视频录制开始2");
//            new CanvasFrame("as").showImage(grabber.grabImage());
            Frame frame;
            int count = 0;
            while((count < 25 * 40) && (frame = grabber.grabFrame()) != null){
                recorder.record(frame);
                count++;

            }

            recorder.stop();
            grabber.stop();
            grabber.release();
        } finally {
            grabber.stop();
        }
    }

    private static HaikangRtspBean getHaikangRtspBean(String cameraIndexCode, String beginTime, String endTime) {
        RemoteHaiKang remoteHaiKang = ToolHaiKangVideo.initHaiKang("40289f5a7e3c994d017e3c998daf0000");
        String res = remoteHaiKang.getOldStreamUrlByCameraIndexCode(cameraIndexCode, EnumStreamUrlProtocol.PROTOCOL_RTSP.getProtocolName(),
                LocalDateTimeUtil.parse(beginTime, Constant.DATE_FORMAT_STAND), LocalDateTimeUtil.parse(endTime, Constant.DATE_FORMAT_STAND));
        HaikangRtspBean bean =  new Gson().fromJson(res, HaikangRtspBean.class);
        return bean;
    }

    public FFmpegFrameGrabber createGrabber(String rtsp) {
        // 获取视频源
        try {
            FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(rtsp);
            grabber.setOption("rtsp_transport", "tcp");
            grabber.setOption("thread_queue_size", "512");
            grabber.setOption("analyzeduration", "1024");
            grabber.setOption("probesize", "5000000");
            grabber.setOption("rtsp_flags", "prefer_tcp");
//             grabber.setOption("--enable-decoder", "h264");
//             grabber.setOption("--enable-parser", "h264");
//             grabber.setOption("--enable-bsf", "extract_extradata");
//             grabber.setOption("--enable-muxer", "flv");

            // 设置帧率
            grabber.setFrameRate(30);

            // 设置获取的视频宽度
            grabber.setImageWidth(1920);
            // 设置获取的视频高度
            grabber.setImageHeight(1080);
            // 设置视频bit率
            grabber.setVideoBitrate(3000000);
            // 音频编/解码器
//            grabber.setVideoCodec(avcodec.AV_CODEC_ID_AAC);
//            grabber.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
            return grabber;
        } catch (FrameGrabber.Exception e) {
            StaticLog.error("create rtsp FFmpegFrameGrabber exception: ", e);
            return null;
        }
    }

}
